﻿using System;
using System.Net;
using System.Linq;
using System.ServiceModel;
using Client.SearchServiceReference;

namespace Client
{
    internal class CommandExecuter
    {
        private const string COMMAND_SEARCH = "search";
        private const string COMMAND_EXIT = "exit";

        private readonly ISearchService service;

        internal CommandExecuter(ISearchService service)
        {
            this.service = service;
        }

        public void ExecuteUserCommands()
        {
            Console.Write("> ");
            string line;
            while ((line = Console.ReadLine()) != null && line != COMMAND_EXIT)
            {
                try
                {
                    var args = line.Split(' ');
                    if (args.Length > 0)
                    {
                        var command = args[0];

                        if (command == COMMAND_SEARCH && args.Length >= 4)
                        {
                            Search(args[1], args[2], args[3], args.Length > 4 ? args.Skip(4).ToArray() : null);
                        }
                        else
                        {
                            Console.WriteLine("Unknown command or invalid number of arguments");
                        }
                    }
                }
                catch (CommunicationException e)
                {
                    var exception = e.InnerException as WebException;
                    if (exception != null && exception.Response != null)
                    {
                        var resp = (HttpWebResponse) exception.Response;
                        Console.WriteLine("Failed, {0}", resp.StatusDescription);
                    }
                    else if (e is EndpointNotFoundException)
                    {
                        Console.WriteLine("Failed, server is down");
                    }
                    else
                    {
                        Console.WriteLine("Failed, {0}", e.Message);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Failed to communicate with service: {0}", e.Message);
                }

                Console.Write("> ");
            }
        }

        private void Search(string from, string to, string date, params string[] servers)
        {
            var response = service.Search(from, to, date, servers != null ? string.Join(",", servers) : null);

            if (response != null && response.Length > 0)
            {
                var results = response.ToList();

                results.Sort((at1, at2) => at1.Price.CompareTo(at2.Price));

                foreach (var at in results)
                {
                    Console.WriteLine("{0}$: {1}", at.Price,
                        string.Join(", ",
                            from flight in at.Flights
                            select string.Format("{0}-{1} ({2}, {3})", flight.From, flight.To, flight.Airline, flight.FlightId)
                        )
                    );
                }
            }
        }
    }
}
